﻿/**************************************************************
*
*  (c) Feasa Enterprises Ltd
*  Feasa LED Spectrometer examples
*  Developed by: Carles Martínez Rius
*
*  PROJECT: get_spectrum
*
*  DESCRIPTION: This example demonstrates how do measurements
*  using the Feasa LED Spectrometer and retrieve the resulting
*  spectrum, which is represented in a chart.
*
*  This example uses a dynamic library to access to the
*  functions related to the Spectrometer. This library is read
*  in runtime so you have to be sure that the file feasacom64.dll
*  exists in the same location of the EXE or in windows/system32
*  folder, however some compillers allow to reference the DLL
*  library from alternative locations using absolute or relative
*  paths.
*
*  Note: there are 32 and 64-bit versions of the DLL, so one or
*  the other has to be used depending on the compiler/IDE platform
*  or binary target platform.
*
**************************************************************/ 
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using USB2XXX;
using static System.Windows.Forms.AxHost;
using System.IO;
using System.Threading;
using System.Runtime.CompilerServices;
using System.Diagnostics;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Windows.Input;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using System.Runtime.InteropServices.ComTypes;
using ZedGraph;
using System.IO.Ports;
using System.Security.Cryptography;
using static System.Windows.Forms.LinkLabel;


namespace capture_and_read
{
    public enum ColorName
    {
        Red = 0,
        Green = 1,
        Blue = 2,
        Red1 = 3,
        Green1 = 4,
        Blue1 = 5,
        Color1 = 3,
        Color2 = 4,
        Color3 = 5,
        Color4 = 6,
        Color5 = 7,
        Color6 = 8,
        Sleep = 9,
        Color256 = 10,
    }

    public partial class Form1 : Form
    {
        private bool Btn_Result = true;
        private Stopwatch sw;
        //光谱界面相关
        private DataMode[] dataMode = new DataMode[12];
        private DataMode[] dataMode_2 = new DataMode[12];

        List<byte> NDLB_DIM = new List<byte>();
        /// NDLB_NAD_DIM.txt读取对应位置的亮度系数 <summary>
        List<byte> NDLB_NAD = new List<byte>();
        /// NDLB_NAD_DIM.txt读取对应位置和NAD
        /// </summary>
        /// <returns></returns>
        [DllImport("feasacom64.dll")]
        private static extern int FeasaCom_EnumPorts();

        [DllImport("feasacom64.dll")]
        private static extern int FeasaCom_Open(int CommPort, string Baudrate);

        [DllImport("feasacom64.dll")]
        private static extern int FeasaCom_Close(int CommPort);

        [DllImport("feasacom64.dll")]
        private static extern int FeasaCom_Send(int CommPort, string Command, StringBuilder ResponseText);

        [DllImport("feasacom64.dll")]
        private static extern int FeasaCom_SetResponseTimeout(uint Timeout);

        [DllImport("feasacom64.dll")]
        private static extern int FeasaCom_IsPortAvailable(int CommPort);

        [DllImport("feasacom64.dll")]
        private static extern int FeasaCom_SpectrometerDark(int CommPort, int isPWM, int UseCustomExposure, float ExposureTime);

        Dictionary<ColorName, double[]> xyz = new Dictionary<ColorName, double[]>(); //RGB波长的色坐标

        Threshold_Reference threshold_Ref = new Threshold_Reference();


        Int32 DevHandle = 0;
        Byte LINIndex = 1;
        int portNumber = 0;
        int portNumber1 = 0;
        bool toomos_connect_state = false;
        int Lit_wait_time = 700;
        int fease_connect_state = 0;
        int fease_connect_state1 = 0;
        byte[] param1 = null;
        byte[] param2 = null;
        byte[] param3 = null;
        byte[] param4 = null;
        byte[] param5 = null;
        byte[] brightness = new byte[] { 0xBA, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0 };
        byte[] PN_Voltage = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
        byte[] Tempruture = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

        byte[] PN_Voltage1 = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
        byte[] Tempruture1 = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };


        byte NDLB_CURRENT_NAD = 0;
        byte NDLB_CURRENT_DIM = 0;
        int version1 = 0;
        int version2 = 0;
        int Own_version = 0;
        
        byte Lin_sign = 0;
        byte end_flag = 0;
        private bool flag = false;  // 标志变量，表示 lstPorts 是否选中端口
        private bool flag1 = false; // 标志变量，表示 lstPorts1 是否选中端口
        bool enter_enable = true; // 标志变量，表示 lstPorts1 是否选中端口
        int Version1 = 0;
        int Version2 = 0;
        byte PID = 0;
        int currentnum = 0;

        private byte[] GetUartCmd(ColorName color)
        {
            byte[] param = null;
            if (PID == 0x14)
            {
                if (color == ColorName.Color1)
                {
                    param = new byte[] { PID, 0x79, 0x64, 0x00, 0x00, 0x00 };
                }
                else if (color == ColorName.Color2)
                {
                    param = new byte[] { PID, 0x45, 0x64, 0x00, 0x00, 0x00 };
                }
                else if (color == ColorName.Color3)
                {
                    param = new byte[] { PID, 0x03, 0x64, 0x00, 0x00, 0x00 };
                }
                else if (color == ColorName.Color4)
                {
                    param = new byte[] { PID, 0x54, 0x64, 0x00, 0x00, 0x00 };
                }
                else if (color == ColorName.Color5)
                {
                    param = new byte[] { PID, 0x0F, 0x64, 0x00, 0x00, 0x00 };
                }
            }
            else
            {
                if (color == ColorName.Color1)
                {
                    param = new byte[] { PID, 0x79, 0x64, 0x00, 0x00, 0x00 };
                }
                else if (color == ColorName.Color2)
                {
                    param = new byte[] { PID, 0x45, 0x64, 0x00, 0x00, 0x00 };
                }
                else if (color == ColorName.Color3)
                {
                    param = new byte[] { PID, 0x03, 0x64, 0x00, 0x00, 0x00 };
                }
                else if (color == ColorName.Color4)
                {
                    param = new byte[] { PID, 0x54, 0x64, 0x00, 0x00, 0x00 };
                }
                else if (color == ColorName.Color5)
                {
                    param = new byte[] { PID, 0x0F, 0x64, 0x00, 0x00, 0x00 };
                }
            }
            return param;
        }
       
        public Form1()
        {
            InitializeComponent();
            this.KeyPreview = true; // 确保窗体可以捕获所有按键事件
            this.KeyDown += MainWindow_KeyDown;
            textBox1.TextChanged += TextBox1_TextChanged;
            textBox2.TextChanged += TextBox2_TextChanged;
            // 为列表控件的SelectedIndexChanged事件添加事件处理器
            lstPorts.SelectedIndexChanged += new EventHandler(LstPorts_SelectedIndexChanged);
            lstPorts1.SelectedIndexChanged += new EventHandler(LstPorts1_SelectedIndexChanged);

            // 设置TreeView的DrawMode为自定义绘制模式
            location_choose.DrawMode = TreeViewDrawMode.OwnerDrawText;

            // 绑定DrawNode事件
            location_choose.DrawNode += new DrawTreeNodeEventHandler(treeView1_DrawNode);

            // 设置背景色
            location_choose.BackColor = Color.LightGray; // 设置整个控件的背景色

            string filePath = "NDLB_NAD_DIM.txt";
            try
            {
                StreamReader reader = new StreamReader(filePath) ;
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error reading file: " + ex.Message);
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            int i;
            for (i = 1; i <= 100; i++)
            {
                if (FeasaCom_IsPortAvailable(i) == 1)
                {
                    lstPorts.Items.Add(i.ToString());
                    lstPorts1.Items.Add(i.ToString());
                }
            }
            //Select the first port of the list
            //if (lstPorts.Items.Count > 0) lstPorts.SelectedIndex = 0;
            Txt_ReadView();
        }

        private void CmdRead_Click(object sender, EventArgs e)
        {
            int resp;
            double lumen;
            var lumen_R = 1000;
            var lumen_G = 1000;
            var lumen_B = 1000;

            double lumen1;
            var lumen_R1 = 1000;
            var lumen_G1 = 1000;
            var lumen_B1 = 1000;

            byte color_check = 0;
            byte color_check1 = 0;
            byte[] param = new byte[10];
            byte[] PN_buffer = new byte[10];
            byte[] Red_temp = new byte[2];
            byte[] Green_temp = new byte[2];
            byte[] Blue_temp = new byte[2];
            byte[] Red_temp1 = new byte[2];
            byte[] Green_temp1 = new byte[2];
            byte[] Blue_temp1 = new byte[2];
            byte[] sign1 = new byte[10];
            byte[] sign2 = new byte[10];
            byte[] sign3 = new byte[10];
            byte[] sign11 = new byte[10];
            byte[] sign12 = new byte[10];
            byte[] sign13 = new byte[10];


            //Set the port number
            /** This variable should have enough size to ensure that the response for all the commands fits in ***/
            StringBuilder buffer = new StringBuilder(64004); //This values ensures the size of the data received for the lowest resolution possible
            StringBuilder buffer1 = new StringBuilder(64004);
            StringBuilder buffer2 = new StringBuilder(64004);
            StringBuilder buffer3 = new StringBuilder(64004);

            param1 = new byte[] { 0x3C, 0x7F, 0x10, 0x08, 0xBB, 0x00, 0x11, 0xFF, 0x00, 0x9B }; //顶空图莫斯测试指令（红色点亮）
            param2 = new byte[] { 0x3C, 0x7F, 0x21, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x5F }; //顶空图莫斯测试指令（白色点亮）
            param3 = new byte[] { 0x3C, 0x7F, 0x10, 0x08, 0xBB, 0x00, 0x11, 0x00, 0xFF, 0x9B }; //顶空图莫斯测试指令（红色点亮）
            param4 = new byte[] { 0x3C, 0x7F, 0x21, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x5E }; //顶空图莫斯测试指令（红色点亮）
            param5 = new byte[] { 0x3C, 0x7F, 0x10, 0x08, 0xBB, 0x00, 0x11, 0x00, 0x00, 0x9B }; //顶空图莫斯测试指令（红色点亮）

            enter_enable = false; //按下enter开始标定后立马禁用enter，防止多次触发
            
            txtLog.Text = "";// 清空标定数据
            richTextBox1.Text = "";// 清空标定数据
            param = new byte[] { 0x3C, 0x7F, 0x04, 0xBB, 0x00, 0x06, 0x00, 0xFF, 0xFF, 0x00 };
            CRC(param);
            Lin_MasterWrite(param);
            Thread.Sleep(300);
            Lin_MasterWrite(param);

            Thread.Sleep(300);
            if (flag)
            {
                for(int a=0;a<10;a++)
                {
                    param = new byte[] { 0x3C, 0x7F, 0x03, 0xBA, 0x00, 0x22, 0xFF, 0xFF, 0xFF, 0x00 };
                    CRC(param);
                    Lin_MasterWrite0(param);

                    Thread.Sleep(50);
                    USB2LIN_EX.LIN_EX_MasterRead(DevHandle, 0, 0x7D, sign1);
                    Thread.Sleep(50);
                    USB2LIN_EX.LIN_EX_MasterRead(DevHandle, 0, 0x7D, sign2);
                    Thread.Sleep(50);
                    USB2LIN_EX.LIN_EX_MasterRead(DevHandle, 0, 0x7D, sign3);
                    Thread.Sleep(50);
                    Version1 = sign2[5] + sign2[4] * 256 + sign2[3] * 65536 + sign2[2] * 16777216;
                    Version2 = sign3[3] + sign3[2] * 256 + sign2[7] * 65536 + sign2[6] * 16777216;
                    if (Version1 != 0)
                    {
                        break;
                    }
                }
                
               
                Thread.Sleep(30);

                if (version1 != Version1|| version2 != Version2)
                {
                    MessageBox.Show("1号位灯头版本号与管理员设置不一致!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                } 
            }

            if (flag1)
            {
                for (int b = 0; b < 10; b++)
                {
                    param = new byte[] { 0x3C, 0x7F, 0x03, 0xBA, 0x00, 0x22, 0xFF, 0xFF, 0xFF, 0x00 };
                    CRC(param);
                    Lin_MasterWrite1(param);

                    Thread.Sleep(50);
                    USB2LIN_EX.LIN_EX_MasterRead(DevHandle, 1, 0x7D, sign11);
                    Thread.Sleep(50);
                    USB2LIN_EX.LIN_EX_MasterRead(DevHandle, 1, 0x7D, sign12);
                    Thread.Sleep(50);
                    USB2LIN_EX.LIN_EX_MasterRead(DevHandle, 1, 0x7D, sign13);
                    Thread.Sleep(50);
                    Version1 = sign12[5] + sign12[4] * 256 + sign12[3] * 65536 + sign12[2] * 16777216;
                    Version2 = sign13[3] + sign13[2] * 256 + sign12[7] * 65536 + sign12[6] * 16777216;
                    if (Version1 != 0)
                    {
                        break;
                    }
                }
                Thread.Sleep(30);

                if (version1 != Version1 || version2 != Version2)
                {
                    MessageBox.Show("2号位灯头版本号与管理员设置不一致!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }
            }

            if (NDLB_CURRENT_NAD == 0 || NDLB_CURRENT_DIM == 0)
            {
                MessageBox.Show("请选择所标定灯头的位置!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
            //Clear the Results box
            //toomos_connect();
            /*This command enumerates the existing ports to find out
            what are the serial ports existing on your computer and
            the devices connected to them. You need to execute this
            command everytime you plug or unplug a Feasa Spectrometer*/
            

            //Open port
            if (fease_connect_state == 1)
            {
                //FeasaCom_SpectrometerDark(portNumber, 0, 0, 0);
                //No error

                //Set the desired Timeout (if it is never specified in the program, by default has a value of 3 seconds)
                //The maximum value can be 32 seconds (32000 ms)
                FeasaCom_SetResponseTimeout(3000);
                //txtLog.Text = String.Concat(txtLog.Text, "Timeout set to: 10000ms\r\n"); //Log

                //Set Wavelength resolution
                //You can notice that there is no need to send the CR + LF characters (the command Send does it for you automatically

                resp = FeasaCom_Send(portNumber, "SetAverage" + Averagetimes.Value.ToString("00"), buffer);//设置光谱仪测量平均次数
                if (resp == -1)
                {
                    MessageBox.Show("光谱仪响应错误!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    FeasaCom_Close(portNumber);
                    return;
                }
                else if (resp == 0)
                {
                    //Show alert message
                    MessageBox.Show("光谱仪响应超时!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    FeasaCom_Close(portNumber);
                    return;
                }
            }
            //用于唤醒
            PN_buffer = new byte[] { 0x3C, 0x7F, 0x04, 0xBB, 0x00, 0x06, 0x00, 0xFF, 0xFF, 0x00 };
            CRC(PN_buffer);
            Lin_MasterWrite(PN_buffer);
            Thread.Sleep(200);
            //读取写入温度
            PN_buffer = new byte[] { 0x3C, 0x7F, 0x04, 0xBB, 0x00, 0x21, 0x01, 0xFF, 0xFF, 0x00 };
            CRC(PN_buffer);
            for (int i = 0; i < 3; i++)
            {
                Lin_MasterWrite(PN_buffer);
                Thread.Sleep(300);
            }
           
            if (flag)
            {
                PN_buffer = new byte[] { 0x3C, 0x7F, 0x04, 0xBA, 0x00, 0x02, 0x00, 0xFF, 0xFF, 0x00 };
                CRC(PN_buffer);
                Lin_MasterWrite0(PN_buffer);
                Thread.Sleep(10);
                USB2LIN_EX.LIN_EX_MasterRead(DevHandle, 0, 0x7D, Tempruture);
                Thread.Sleep(10);
                USB2LIN_EX.LIN_EX_MasterRead(DevHandle, 0, 0x7D, PN_Voltage);
                Thread.Sleep(200);
            }
            if (flag1)
            {
                PN_buffer = new byte[] { 0x3C, 0x7F, 0x04, 0xBA, 0x00, 0x02, 0x00, 0xFF, 0xFF, 0x00 };
                CRC(PN_buffer);
                Lin_MasterWrite1(PN_buffer);
                Thread.Sleep(10);
                USB2LIN_EX.LIN_EX_MasterRead(DevHandle, 1, 0x7D, Tempruture1);
                Thread.Sleep(10);
                USB2LIN_EX.LIN_EX_MasterRead(DevHandle, 1, 0x7D, PN_Voltage1);
                Thread.Sleep(10);
            }

            PN_buffer = new byte[] { 0x3C, 0x7F, 0x04, 0xBB, 0x00, 0x21, 0x00, 0xFF, 0xFF, 0x00 };
            CRC(PN_buffer);
            Lin_MasterWrite(PN_buffer);
            Thread.Sleep(10);
            if (flag)
            {
                PN_buffer = new byte[] { 0x3C, 0x7F, 0x10, 0x0B, 0xBB, 0x00, 0x04, Tempruture[5], 0x18, 0x00 };
                CRC(PN_buffer);
                Lin_MasterWrite0(PN_buffer);
                Thread.Sleep(10);
                PN_buffer = new byte[] { 0x3C, 0x7F, 0x21, Tempruture[7], PN_Voltage[2], PN_Voltage[3], PN_Voltage[4], PN_Voltage[5], PN_Voltage[6], 0x00 };
                CRC(PN_buffer);
                Lin_MasterWrite0(PN_buffer);
            }
            if (flag1)
            {
                PN_buffer = new byte[] { 0x3C, 0x7F, 0x10, 0x0B, 0xBB, 0x00, 0x04, Tempruture1[5], 0x18, 0x00 };
                CRC(PN_buffer);
                Lin_MasterWrite1(PN_buffer);
                Thread.Sleep(10);
                PN_buffer = new byte[] { 0x3C, 0x7F, 0x21, Tempruture1[7], PN_Voltage1[2], PN_Voltage1[3], PN_Voltage1[4], PN_Voltage1[5], PN_Voltage1[6], 0x00 };
                CRC(PN_buffer);
                Lin_MasterWrite1(PN_buffer);
            }
            //RGB测量与写数据
            //You can notice that there is no need to send the CR + LF characters (the command Send does it for you automatically)
            Lin_MasterWrite(param1);
            Thread.Sleep(300);
            //param = new byte[] { 0x3C, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00 };
            //CRC(param);
            //Lin_MasterWrite(param);
            //Thread.Sleep(4000);
            for (int i = 0; i < 4; i++)
            {
                //Lin_MasterWrite(param1);
                Thread.Sleep(500);
                if (i == 0)
                {
                    Lin_MasterWrite(param1);
                    Lin_MasterWrite(param2);
                    Lin_MasterWrite(param1);
                    Lin_MasterWrite(param2);
                    Thread.Sleep(500);
                    if (flag)
                    {
                        resp = FeasaCom_Send(portNumber, "CAPTURE300", buffer);
                        resp = FeasaCom_Send(portNumber, "GETXY", buffer);
                        string[] numbers = buffer.ToString().Split(' '); // 使用空格字符拆分字符串
                        if (numbers.Length == 2 && numbers[0] != "ERROR:")
                        {
                            // 使用 Parse() 方法将字符串转换为 double 型数字
                            double color_x = double.Parse(numbers[0]);
                            double color_y = double.Parse(numbers[1]);
                            if (xyz.ContainsKey(ColorName.Red))
                            {
                                xyz[ColorName.Red][0] = color_x;
                                xyz[ColorName.Red][1] = color_y;
                            }
                            else
                            {
                                xyz.Add(ColorName.Red, new double[] { color_x, color_y });
                            }
                        }
                        resp = FeasaCom_Send(portNumber, "getluminousflux", buffer1);
                        string valueString = buffer1.ToString().Split(' ')[0];
                        string error = "ERROR: UNDERRANGE";
                        bool resp1 = string.Equals(buffer1.ToString(), error);
                        PN_buffer = new byte[] { 0x3C, 0x7F, 0x04, 0xBA, 0x00, 0x02, 0x00, 0xFF, 0xFF, 0x00 };
                        CRC(PN_buffer);
                        Lin_MasterWrite(PN_buffer);
                        Thread.Sleep(10);
                        USB2LIN_EX.LIN_EX_MasterRead(DevHandle, 0, 0x7D, Tempruture);
                        Red_temp[0] = Tempruture[5];
                        Red_temp[1] = Tempruture[6];
                        if (resp1)
                        {
                            MessageBox.Show("收光器1没有收到红色光!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                            return;
                        }
                        else
                        {
                            lumen = Double.Parse(valueString);
                            lumen_R = (int)(lumen * 1000);
                            txtLog.Text = String.Concat(txtLog.Text, "NAD: ", NDLB_CURRENT_NAD, "     ");
                            txtLog.Text = String.Concat(txtLog.Text, "DIM: ", NDLB_CURRENT_DIM, "\r\n\r\n");

                            txtLog.Text = String.Concat(txtLog.Text, "Red data:\r\n", buffer.ToString(), "  ");
                            txtLog.Text = String.Concat(txtLog.Text, lumen_R, "\r\n");
                            txtLog.ScrollToCaret();
                        }
                    }
                    if (flag1)
                    {
                        resp = FeasaCom_Send(portNumber1, "CAPTURE300", buffer2);
                        resp = FeasaCom_Send(portNumber1, "GETXY", buffer2);
                        string[] numbers = buffer2.ToString().Split(' '); // 使用空格字符拆分字符串
                        if (numbers.Length == 2 && numbers[0] != "ERROR:")
                        {
                            // 使用 Parse() 方法将字符串转换为 double 型数字
                            double color_x = double.Parse(numbers[0]);
                            double color_y = double.Parse(numbers[1]);
                            if (xyz.ContainsKey(ColorName.Red1))
                            {
                                xyz[ColorName.Red1][0] = color_x;
                                xyz[ColorName.Red1][1] = color_y;
                            }
                            else
                            {
                                xyz.Add(ColorName.Red1, new double[] { color_x, color_y });
                            }
                        }
                        resp = FeasaCom_Send(portNumber1, "getluminousflux", buffer3);
                        string valueString = buffer3.ToString().Split(' ')[0];
                        string error = "ERROR: UNDERRANGE";
                        bool resp1 = string.Equals(buffer3.ToString(), error);
                        PN_buffer = new byte[] { 0x3C, 0x7F, 0x04, 0xBA, 0x00, 0x02, 0x00, 0xFF, 0xFF, 0x00 };
                        CRC(PN_buffer);
                        Lin_MasterWrite(PN_buffer);
                        Thread.Sleep(10);
                        USB2LIN_EX.LIN_EX_MasterRead(DevHandle, 1, 0x7D, Tempruture1);
                        Red_temp1[0] = Tempruture1[5];
                        Red_temp1[1] = Tempruture1[6];
                        if (resp1)
                        {
                            MessageBox.Show("收光器2没有收到红色光!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                            return;
                        }
                        else
                        {
                            lumen1 = Double.Parse(valueString);
                            lumen_R1 = (int)(lumen1 * 1000);
                            richTextBox1.Text = String.Concat(richTextBox1.Text, "NAD: ", NDLB_CURRENT_NAD, "     ");
                            richTextBox1.Text = String.Concat(richTextBox1.Text, "DIM: ", NDLB_CURRENT_DIM, "\r\n\r\n");

                            richTextBox1.Text = String.Concat(richTextBox1.Text, "Red data:\r\n", buffer2.ToString(), "  ");
                            richTextBox1.Text = String.Concat(richTextBox1.Text, lumen_R1, "\r\n");
                            richTextBox1.ScrollToCaret();
                        }
                    }
                    //param = new byte[] { 0x3C, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00 };
                    //CRC(param);
                    //Lin_MasterWrite(param);
                    //Thread.Sleep(2000);
                }

                if (i == 1)
                {
                    Lin_MasterWrite(param2);
                    Lin_MasterWrite(param3);
                    Lin_MasterWrite(param2);
                    Lin_MasterWrite(param3);
                    Thread.Sleep(500);
                    if (flag)
                    {
                        resp = FeasaCom_Send(portNumber, "CAPTURE300", buffer);
                        resp = FeasaCom_Send(portNumber, "GETXY", buffer);
                        string[] numbers = buffer.ToString().Split(' '); // 使用空格字符拆分字符串
                        if (numbers.Length == 2 && numbers[0] != "ERROR:")
                        {
                            // 使用 Parse() 方法将字符串转换为 double 型数字
                            double color_x = double.Parse(numbers[0]);
                            double color_y = double.Parse(numbers[1]);

                            if (xyz.ContainsKey(ColorName.Green))
                            {
                                xyz[ColorName.Green][0] = color_x;
                                xyz[ColorName.Green][1] = color_y;
                            }
                            else
                            {
                                xyz.Add(ColorName.Green, new double[] { color_x, color_y });
                            }
                        }

                        resp = FeasaCom_Send(portNumber, "getluminousflux", buffer1);
                        string valueString = buffer1.ToString().Split(' ')[0];
                        string error = "ERROR: UNDERRANGE";
                        bool resp1 = string.Equals(buffer1.ToString(), error);
                        PN_buffer = new byte[] { 0x3C, 0x7F, 0x04, 0xBA, 0x00, 0x02, 0x00, 0xFF, 0xFF, 0x00 };
                        CRC(PN_buffer);
                        Lin_MasterWrite(PN_buffer);
                        Thread.Sleep(10);
                        USB2LIN_EX.LIN_EX_MasterRead(DevHandle, 0, 0x7D, Tempruture);
                        Green_temp[0] = Tempruture[5];
                        Green_temp[1] = Tempruture[6];
                        if (resp1)
                        {
                            MessageBox.Show("收光器没有收到绿色光!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                            return;
                        }
                        else
                        {
                            lumen = Double.Parse(valueString);
                            lumen_G = (int)(lumen * 1000);
                            txtLog.Text = String.Concat(txtLog.Text, "Green data:\r\n", buffer.ToString(), "  ");
                            txtLog.Text = String.Concat(txtLog.Text, lumen_G, "\r\n");
                            txtLog.ScrollToCaret();
                        }
                    }
                    if (flag1)
                    {
                        resp = FeasaCom_Send(portNumber1, "CAPTURE300", buffer2);
                        resp = FeasaCom_Send(portNumber1, "GETXY", buffer2);
                        string[] numbers = buffer2.ToString().Split(' '); // 使用空格字符拆分字符串
                        if (numbers.Length == 2 && numbers[0] != "ERROR:")
                        {
                            // 使用 Parse() 方法将字符串转换为 double 型数字
                            double color_x = double.Parse(numbers[0]);
                            double color_y = double.Parse(numbers[1]);

                            if (xyz.ContainsKey(ColorName.Green1))
                            {
                                xyz[ColorName.Green1][0] = color_x;
                                xyz[ColorName.Green1][1] = color_y;
                            }
                            else
                            {
                                xyz.Add(ColorName.Green1, new double[] { color_x, color_y });
                            }
                        }

                        resp = FeasaCom_Send(portNumber1, "getluminousflux", buffer3);
                        string valueString = buffer3.ToString().Split(' ')[0];
                        string error = "ERROR: UNDERRANGE";
                        bool resp1 = string.Equals(buffer3.ToString(), error);
                        PN_buffer = new byte[] { 0x3C, 0x7F, 0x04, 0xBA, 0x00, 0x02, 0x00, 0xFF, 0xFF, 0x00 };
                        CRC(PN_buffer);
                        Lin_MasterWrite(PN_buffer);
                        Thread.Sleep(10);
                        USB2LIN_EX.LIN_EX_MasterRead(DevHandle, 1, 0x7D, Tempruture);
                        Green_temp1[0] = Tempruture[5];
                        Green_temp1[1] = Tempruture[6];
                        if (resp1)
                        {
                            MessageBox.Show("收光器没有收到绿色光!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                            return;
                        }
                        else
                        {
                            lumen1 = Double.Parse(valueString);
                            lumen_G1 = (int)(lumen1 * 1000);
                            richTextBox1.Text = String.Concat(richTextBox1.Text, "Green data:\r\n", buffer2.ToString(), "  ");
                            richTextBox1.Text = String.Concat(richTextBox1.Text, lumen_G1, "\r\n");
                            richTextBox1.ScrollToCaret();
                        }
                    }
                    //param = new byte[] { 0x3C, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00 };
                    //CRC(param);
                    //Lin_MasterWrite(param);
                    //Thread.Sleep(4000);
                }

                if (i == 2)
                {
                    Lin_MasterWrite(param4);
                    Lin_MasterWrite(param5);
                    Lin_MasterWrite(param4);
                    Lin_MasterWrite(param5);
                    Thread.Sleep(500);
                    if (flag)
                    {
                        resp = FeasaCom_Send(portNumber, "CAPTURE300", buffer);
                        resp = FeasaCom_Send(portNumber, "GETXY", buffer);
                        string[] numbers = buffer.ToString().Split(' '); // 使用空格字符拆分字符串
                        if (numbers.Length == 2 && numbers[0] != "ERROR:")
                        {
                            // 使用 Parse() 方法将字符串转换为 double 型数字
                            double color_x = double.Parse(numbers[0]);
                            double color_y = double.Parse(numbers[1]);
                            if (xyz.ContainsKey(ColorName.Blue))
                            {
                                xyz[ColorName.Blue][0] = color_x;
                                xyz[ColorName.Blue][1] = color_y;
                            }
                            else
                            {
                                xyz.Add(ColorName.Blue, new double[] { color_x, color_y });
                            }
                        }
                        resp = FeasaCom_Send(portNumber, "getluminousflux", buffer1);
                        string valueString = buffer1.ToString().Split(' ')[0];
                        string error = "ERROR: UNDERRANGE";
                        bool resp1 = string.Equals(buffer1.ToString(), error);
                        PN_buffer = new byte[] { 0x3C, 0x7F, 0x04, 0xBA, 0x00, 0x02, 0x00, 0xFF, 0xFF, 0x00 };
                        CRC(PN_buffer);
                        Lin_MasterWrite(PN_buffer);
                        Thread.Sleep(10);
                        USB2LIN_EX.LIN_EX_MasterRead(DevHandle, 0, 0x7D, Tempruture);
                        Blue_temp[0] = Tempruture[5];
                        Blue_temp[1] = Tempruture[6];
                        if (resp1)
                        {
                            MessageBox.Show("收光器没有收到蓝色光!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                            return;
                        }
                        else
                        {
                            lumen = Double.Parse(valueString);
                            lumen_B = (int)(lumen * 1000);
                            txtLog.Text = String.Concat(txtLog.Text, "Blue data:\r\n", buffer.ToString(), "  ");
                            txtLog.Text = String.Concat(txtLog.Text, lumen_B, "\r\n");
                            txtLog.ScrollToCaret();
                            txtLog.Text = String.Concat(txtLog.Text, "\r\n");
                        }
                    }
                    if (flag1)
                    {
                        resp = FeasaCom_Send(portNumber1, "CAPTURE300", buffer2);
                        resp = FeasaCom_Send(portNumber1, "GETXY", buffer2);
                        string[] numbers = buffer2.ToString().Split(' '); // 使用空格字符拆分字符串
                        if (numbers.Length == 2 && numbers[0] != "ERROR:")
                        {
                            // 使用 Parse() 方法将字符串转换为 double 型数字
                            double color_x = double.Parse(numbers[0]);
                            double color_y = double.Parse(numbers[1]);
                            if (xyz.ContainsKey(ColorName.Blue1))
                            {
                                xyz[ColorName.Blue1][0] = color_x;
                                xyz[ColorName.Blue1][1] = color_y;
                            }
                            else
                            {
                                xyz.Add(ColorName.Blue1, new double[] { color_x, color_y });
                            }
                        }
                        resp = FeasaCom_Send(portNumber1, "getluminousflux", buffer3);
                        string valueString = buffer3.ToString().Split(' ')[0];
                        string error = "ERROR: UNDERRANGE";
                        bool resp1 = string.Equals(buffer3.ToString(), error);
                        PN_buffer = new byte[] { 0x3C, 0x7F, 0x04, 0xBA, 0x00, 0x02, 0x00, 0xFF, 0xFF, 0x00 };
                        CRC(PN_buffer);
                        Lin_MasterWrite(PN_buffer);
                        Thread.Sleep(10);
                        USB2LIN_EX.LIN_EX_MasterRead(DevHandle, 1, 0x7D, Tempruture);
                        Blue_temp1[0] = Tempruture[5];
                        Blue_temp1[1] = Tempruture[6];
                        if (resp1)
                        {
                            MessageBox.Show("收光器没有收到蓝色光!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                            return;
                        }
                        else
                        {
                            lumen1 = Double.Parse(valueString);
                            lumen_B1 = (int)(lumen1 * 1000);
                            richTextBox1.Text = String.Concat(richTextBox1.Text, "Blue data:\r\n", buffer2.ToString(), "  ");
                            richTextBox1.Text = String.Concat(richTextBox1.Text, lumen_B1, "\r\n");
                            richTextBox1.ScrollToCaret();
                            richTextBox1.Text = String.Concat(richTextBox1.Text, "\r\n");
                        }
                    }
                    //param = new byte[] { 0x3C, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00 };
                    //CRC(param);
                    //Lin_MasterWrite(param);
                    //Thread.Sleep(3000);
                }
                if (i == 3)
                {
                    Lin_MasterWrite(param2);
                    Lin_MasterWrite(param5);
                    Lin_MasterWrite(param2);
                    Lin_MasterWrite(param5);
                    if (flag)
                    {
                        for (int write_times = 0; write_times < 2; write_times++)
                        {
                            var temp_x = (int)System.Math.Floor(xyz[ColorName.Red][0] * 65535);
                            var temp_y = (int)System.Math.Floor(xyz[ColorName.Red][1] * 65535);
                            param = new byte[] { 0x3C, 0x7F, 0x10, 0x19, 0xBB, 0x00, 0x01, 0x00, Red_temp[1], 0x00 };
                            CRC(param);
                            Lin_MasterWrite0(param);
                            param = new byte[] { 0x3C, 0x7F, 0x21, Green_temp[1], Blue_temp[1], (byte)((temp_x >> 8) & 0xFF), (byte)(temp_x & 0xFF), (byte)((temp_y >> 8) & 0xFF), (byte)(temp_y & 0xFF), 0x00 };
                            CRC(param);
                            Lin_MasterWrite0(param);

                            temp_x = (int)System.Math.Floor(xyz[ColorName.Green][0] * 65535);
                            temp_y = (int)System.Math.Floor(xyz[ColorName.Green][1] * 65535);
                            param = new byte[] { 0x3C, 0x7F, 0x22, (byte)((temp_x >> 8) & 0xFF), (byte)(temp_x & 0xFF), (byte)((temp_y >> 8) & 0xFF), (byte)(temp_y & 0xFF), 0x00, 0x00, 0x00 };
                            temp_x = (int)System.Math.Floor(xyz[ColorName.Blue][0] * 65535);
                            temp_y = (int)System.Math.Floor(xyz[ColorName.Blue][1] * 65535);
                            param[7] = (byte)(temp_x >> 8 & 0xFF);
                            param[8] = (byte)(temp_x & 0xFF);
                            CRC(param);
                            Lin_MasterWrite0(param);
                            param = new byte[] { 0x3C, 0x7F, 0x23, (byte)((temp_y >> 8) & 0xFF), (byte)(temp_y & 0xFF), (byte)((lumen_R >> 8) & 0xFF), (byte)(lumen_R & 0xFF), (byte)((lumen_G >> 8) & 0xFF), (byte)(lumen_G & 0xFF), 0x00 };
                            CRC(param);
                            Lin_MasterWrite0(param);
                            param = new byte[] { 0x3C, 0x7F, 0x24, (byte)((lumen_B >> 8) & 0xFF), (byte)(lumen_B & 0xFF), 0xFF, 0xFF, 0xFF, 0xFF, 0x00 };
                            CRC(param);
                            Lin_MasterWrite0(param);
                            Thread.Sleep(200);
                        }
                        param = new byte[] { 0x3C, 0x7F, 0x06, 0xB0, 0xFF, 0x7F, 0xFF, 0xFF, NDLB_CURRENT_NAD, 0x00 };
                        CRC(param);
                        Lin_MasterWrite0(param);
                        Thread.Sleep(30);
                        //亮度限制
                        int R_m_Intensity = (int)(lumen_R * 0.50);
                        int G_m_Intensity = (int)(lumen_G * 0.80);
                        int B_m_Intensity = (int)(lumen_B * 0.80);

                        param = new byte[] { 0x3C, 0x7F, 0x10, 0x0E, 0xBB, 0x00, 0x17, 0x55, 0x53, 0x00 };
                        CRC(param);
                        Lin_MasterWrite0(param);
                        param = new byte[] { 0x3C, 0x7F, 0x21, 0x55, 0x53, (byte)((R_m_Intensity >> 8) & 0xFF), (byte)(R_m_Intensity & 0xFF), (byte)((G_m_Intensity >> 8) & 0xFF), (byte)(G_m_Intensity & 0xFF), 0x00 };
                        CRC(param);
                        Lin_MasterWrite(param);
                        param = new byte[] { 0x3C, 0x7F, 0x22, (byte)((B_m_Intensity >> 8) & 0xFF), (byte)(B_m_Intensity & 0xFF), 0x00, 0xFF, 0xFF, 0xFF, 0x00 };
                        CRC(param);
                        Lin_MasterWrite0(param);
                        Thread.Sleep(30);
                        int dimming = NDLB_CURRENT_DIM*100;
                        param = new byte[] { 0x3C, 0x7F, 0x10, 0x0A, 0xBB, 0x00, 0x27, 0x00, 0x00, 0x00 };
                        CRC(param);
                        Lin_MasterWrite0(param);
                        Thread.Sleep(30);
                        param = new byte[] { 0x3C, 0x7F, 0x21, (byte)(dimming>>8), (byte)(dimming&0xFF), 0xFF, 0xFF, 0xFF, 0xFF, 0x00 };
                        CRC(param);
                        Lin_MasterWrite0(param);
                        Thread.Sleep(30);

                        DateTime now = DateTime.Now;

                        // 将十进制数字的每一位映射到十六进制
                        int targetHexYear = 0;
                        int targetHexMonth = 0;
                        int targetHexDay = 0;
                        int currentnumber = 0;

                        targetHexYear |= (now.Year / 1000 % 10) << 12; // 千位 -> 0x2000
                        targetHexYear |= (now.Year / 100 % 10) << 8;    // 百位 -> 0x0000
                        targetHexYear |= (now.Year / 10 % 10) << 4;     // 十位 -> 0x0020
                        targetHexYear |= ((now.Year) % 10);                // 个位 -> 0x0005
                        targetHexMonth |= ((now.Month / 10) % 10) << 4;     // 十位 -> 0x0020
                        targetHexMonth |= (now.Month % 10);                // 个位 -> 0x0005
                        targetHexDay |= ((now.Day / 10) % 10) << 4;     // 十位 -> 0x0020
                        targetHexDay |= (now.Day % 10);                // 个位 -> 0x0005


                        currentnumber |= ((currentnum + 1) / 100000 % 10) << 20;
                        currentnumber |= ((currentnum + 1) / 10000 % 10) << 16;
                        currentnumber |= ((currentnum + 1) / 1000 % 10) << 12;
                        currentnumber |= ((currentnum + 1) / 100 % 10) << 8;
                        currentnumber |= ((currentnum + 1) / 10 % 10) << 4;
                        currentnumber |= ((currentnum + 1) % 10);

                        // 只取数字后6位
                        string input = textBox3.Text;
                        string numbersOnly = new string(input.Where(char.IsDigit).ToArray());
                        string last6Numbers = numbersOnly.Length >= 6 ? numbersOnly.Substring(numbersOnly.Length - 6) : numbersOnly;
                      
                        byte[] bytes = new byte[3];

                        // 每2位十进制数字转成一个字节
                        for (int k = 0; k < 3; k++)
                        {
                            string twoDigits = last6Numbers.Substring(k * 2, 2); // "12", "34", "56", "78"
                            bytes[k] = Convert.ToByte(twoDigits); // 转为字节（0x12, 0x34, 0x56, 0x78）
                        }
                        byte[] a1 = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
                        byte[] a2 = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
                        byte[] a3 = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
                        byte[] a4 = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
                        for (int y = 0; y < 10; y++)
                        {
                            param = new byte[] { 0x3C, 0x7F, 0x10, 0x0F, 0xBB, 0x00, 0x29, (byte)(targetHexYear >> 8), (byte)(targetHexYear & 0xFF), 0x00 };
                            CRC(param);
                            Lin_MasterWrite0(param);
                            param = new byte[] { 0x3C, 0x7F, 0x21, (byte)(targetHexMonth), (byte)(targetHexDay), (byte)(currentnumber >> 16), (byte)(currentnumber >> 8 & 0xFF), (byte)(currentnumber & 0xFF), (byte)Own_version, 0x00 };
                            CRC(param);
                            Lin_MasterWrite0(param);
                            param = new byte[] { 0x3C, 0x7F, 0x22, (byte)Lin_sign, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00 };
                            CRC(param);
                            Lin_MasterWrite0(param);
                            
                            param = new byte[] { 0x3C, 0x7F, 0x06, 0xBA, 0x00, 0x28, 0xFF, 0xFF, 0xFF, 0x00 };
                            CRC(param);
                            Lin_MasterWrite0(param);
                            USB2LIN_EX.LIN_EX_MasterRead(DevHandle, 0, 0x7D, a1);
                            USB2LIN_EX.LIN_EX_MasterRead(DevHandle, 0, 0x7D, a2);
                            USB2LIN_EX.LIN_EX_MasterRead(DevHandle, 0, 0x7D, a3);
                            USB2LIN_EX.LIN_EX_MasterRead(DevHandle, 0, 0x7D, a4);
                            if (a4[6] == Lin_sign)
                            {
                                break;
                            }
                        }
                       
                        Thread.Sleep(20);
                    }
                    if (flag1)
                    {
                        for (int write_times = 0; write_times < 2; write_times++)
                        {
                            var temp_x = (int)System.Math.Floor(xyz[ColorName.Red1][0] * 65535);
                            var temp_y = (int)System.Math.Floor(xyz[ColorName.Red1][1] * 65535);
                            param = new byte[] { 0x3C, 0x7F, 0x10, 0x19, 0xBB, 0x00, 0x01, 0x00, Red_temp1[1], 0x00 };
                            CRC(param);
                            Lin_MasterWrite1(param);
                            param = new byte[] { 0x3C, 0x7F, 0x21, Green_temp1[1], Blue_temp1[1], (byte)((temp_x >> 8) & 0xFF), (byte)(temp_x & 0xFF), (byte)((temp_y >> 8) & 0xFF), (byte)(temp_y & 0xFF), 0x00 };
                            CRC(param);
                            Lin_MasterWrite1(param);

                            temp_x = (int)System.Math.Floor(xyz[ColorName.Green1][0] * 65535);
                            temp_y = (int)System.Math.Floor(xyz[ColorName.Green1][1] * 65535);
                            param = new byte[] { 0x3C, 0x7F, 0x22, (byte)((temp_x >> 8) & 0xFF), (byte)(temp_x & 0xFF), (byte)((temp_y >> 8) & 0xFF), (byte)(temp_y & 0xFF), 0x00, 0x00, 0x00 };
                            temp_x = (int)System.Math.Floor(xyz[ColorName.Blue1][0] * 65535);
                            temp_y = (int)System.Math.Floor(xyz[ColorName.Blue1][1] * 65535);
                            param[7] = (byte)(temp_x >> 8 & 0xFF);
                            param[8] = (byte)(temp_x & 0xFF);
                            CRC(param);
                            Lin_MasterWrite1(param);
                            param = new byte[] { 0x3C, 0x7F, 0x23, (byte)((temp_y >> 8) & 0xFF), (byte)(temp_y & 0xFF), (byte)((lumen_R1 >> 8) & 0xFF), (byte)(lumen_R1 & 0xFF), (byte)((lumen_G1 >> 8) & 0xFF), (byte)(lumen_G1 & 0xFF), 0x00 };
                            CRC(param);
                            Lin_MasterWrite1(param);
                            param = new byte[] { 0x3C, 0x7F, 0x24, (byte)((lumen_B1 >> 8) & 0xFF), (byte)(lumen_B1 & 0xFF), 0xFF, 0xFF, 0xFF, 0xFF, 0x00 };
                            CRC(param);
                            Lin_MasterWrite1(param);
                            Thread.Sleep(200);
                        }
                        param = new byte[] { 0x3C, 0x7F, 0x06, 0xB0, 0xFF, 0x7F, 0xFF, 0xFF, NDLB_CURRENT_NAD, 0x00 };
                        CRC(param);
                        Lin_MasterWrite1(param);
                        Thread.Sleep(30);
                        //亮度限制
                        int R_m_Intensity = (int)(lumen_R1 * 0.50);
                        int G_m_Intensity = (int)(lumen_G1 * 0.80);
                        int B_m_Intensity = (int)(lumen_B1 * 0.80);

                        param = new byte[] { 0x3C, 0x7F, 0x10, 0x0E, 0xBB, 0x00, 0x17, 0x55, 0x53, 0x00 };
                        CRC(param);
                        Lin_MasterWrite1(param);
                        param = new byte[] { 0x3C, 0x7F, 0x21, 0x55, 0x53, (byte)((R_m_Intensity >> 8) & 0xFF), (byte)(R_m_Intensity & 0xFF), (byte)((G_m_Intensity >> 8) & 0xFF), (byte)(G_m_Intensity & 0xFF), 0x00 };
                        CRC(param);
                        Lin_MasterWrite(param);
                        param = new byte[] { 0x3C, 0x7F, 0x22, (byte)((B_m_Intensity >> 8) & 0xFF), (byte)(B_m_Intensity & 0xFF), 0x00, 0xFF, 0xFF, 0xFF, 0x00 };
                        CRC(param);
                        Lin_MasterWrite1(param);
                        Thread.Sleep(30);
                        int dimming = NDLB_CURRENT_DIM * 100;
                        param = new byte[] { 0x3C, 0x7F, 0x10, 0x0A, 0xBB, 0x00, 0x27, 0x00, 0x00, 0x00 };
                        CRC(param);
                        Lin_MasterWrite1(param);
                        Thread.Sleep(30);
                        param = new byte[] { 0x3C, 0x7F, 0x21, (byte)(dimming >> 8), (byte)(dimming & 0xFF), 0xFF, 0xFF, 0xFF, 0xFF, 0x00 };
                        CRC(param);
                        Lin_MasterWrite1(param);

                        DateTime now = DateTime.Now;

                        // 将十进制数字的每一位映射到十六进制
                        int targetHexYear = 0;
                        int targetHexMonth = 0;
                        int targetHexDay = 0;
                        int currentnumber = 0;


                        targetHexYear |= (now.Year /1000 % 10) << 12; // 千位 -> 0x2000
                        targetHexYear |= (now.Year /100 % 10) << 8;    // 百位 -> 0x0000
                        targetHexYear |= (now.Year/10 % 10) << 4;     // 十位 -> 0x0020
                        targetHexYear |= ((now.Year ) % 10);                // 个位 -> 0x0005
                        targetHexMonth |= ((now.Month  / 10) % 10) << 4;     // 十位 -> 0x0020
                        targetHexMonth |= (now.Month % 10);                // 个位 -> 0x0005
                        targetHexDay |= ((now.Day / 10) % 10) << 4;     // 十位 -> 0x0020
                        targetHexDay |= (now.Day % 10);                // 个位 -> 0x0005



                        currentnumber |= ((currentnum + 1) / 100000 % 10) << 20;
                        currentnumber |= ((currentnum + 1) / 10000 % 10) << 16;
                        currentnumber |= ((currentnum + 1) / 1000 % 10) << 12;
                        currentnumber |= ((currentnum + 1) / 100 % 10) << 8;
                        currentnumber |= ((currentnum + 1) / 10 % 10) << 4;
                        currentnumber |= ((currentnum + 1) % 10) ;

                        // 只取数字后6位
                        string input = textBox4.Text;
                        string numbersOnly = new string(input.Where(char.IsDigit).ToArray());
                        string last6Numbers = numbersOnly.Length >= 6 ? numbersOnly.Substring(numbersOnly.Length - 6) : numbersOnly;

                        
                        byte[] a1 = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
                        byte[] a2 = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
                        byte[] a3 = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
                        byte[] a4 = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
                        for (int z = 0; z < 10; z++)
                        {
                            param = new byte[] { 0x3C, 0x7F, 0x10, 0x0F, 0xBB, 0x00, 0x29, (byte)(targetHexYear >> 8), (byte)(targetHexYear & 0xFF), 0x00 };
                            CRC(param);
                            Lin_MasterWrite1(param);
                            param = new byte[] { 0x3C, 0x7F, 0x21, (byte)(targetHexMonth), (byte)(targetHexDay), (byte)(currentnumber >> 16), (byte)(currentnumber >> 8 & 0xFF), (byte)(currentnumber&0xFF), (byte)Own_version, 0x00 };
                            CRC(param);
                            Lin_MasterWrite1(param);
                            param = new byte[] { 0x3C, 0x7F, 0x22, (byte)Lin_sign, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00 };
                            CRC(param);
                            Lin_MasterWrite1(param);

                            param = new byte[] { 0x3C, 0x7F, 0x06, 0xBA, 0x00, 0x28, 0xFF, 0xFF, 0xFF,  0x00 };
                            CRC(param);
                            Lin_MasterWrite1(param);
                            USB2LIN_EX.LIN_EX_MasterRead(DevHandle, 1, 0x7D, a1);
                            USB2LIN_EX.LIN_EX_MasterRead(DevHandle, 1, 0x7D, a2);
                            USB2LIN_EX.LIN_EX_MasterRead(DevHandle, 1, 0x7D, a3);
                            USB2LIN_EX.LIN_EX_MasterRead(DevHandle, 1, 0x7D, a4);
                            if (a4[6] == Lin_sign)
                            {
                                break;
                            }

                        }

                        Thread.Sleep(20);
                    }


                }
            }
                //标定完之后，进行颜色检查
                Lin_MasterWrite(GetUartCmd(ColorName.Color1));
                Thread.Sleep(200);
            for (int j = 0; j < 6; j++)
            {
                param = new byte[] { 0x3C, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00 };
                CRC(param);
                Lin_MasterWrite(param);

                if (j == 0)
                {
                    for (int x = 0; x < 10; x++)
                    {
                        Lin_MasterWrite(GetUartCmd(ColorName.Color1));
                        Thread.Sleep(100);
                    }

                    resp = FeasaCom_Send(portNumber, "CAPTURE300", buffer);
                    resp = FeasaCom_Send(portNumber, "GETXY", buffer);
                    resp = FeasaCom_Send(portNumber1, "CAPTURE300", buffer1);
                    resp = FeasaCom_Send(portNumber1, "GETXY", buffer1);
                    string[] numbers = buffer.ToString().Split(' '); // 使用空格字符拆分字符串
                    string[] numbers1 = buffer1.ToString().Split(' '); // 使用空格字符拆分字符串
                    if (flag)
                    {
                        if (numbers.Length == 2 && numbers[0] != "ERROR:")
                        {
                            // 使用 Parse() 方法将字符串转换为 double 型数字
                            double color_x = threshold_Ref.Color1_x - double.Parse(numbers[0]);
                            double color_y = threshold_Ref.Color1_y - double.Parse(numbers[1]);
                            txtLog.Text = String.Concat(txtLog.Text, "COLOR1:\r\n", buffer.ToString(), "  ");
                            txtLog.Text = String.Concat(txtLog.Text, color_x.ToString("F4"), " ", color_y.ToString("F4"), "\r\n");
                            if (color_x < 0.01 && color_x > -0.01 && color_y < 0.01 && color_y > -0.01 && color_check == 0)
                            {
                                color_check = 1;
                            }
                        }
                        else
                        {
                            MessageBox.Show("收光器1没有收到测试色颜色1!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                            return;
                        }
                    }
                    if (flag1)
                    {
                        if (numbers1.Length == 2 && numbers1[0] != "ERROR:")
                        {
                            // 使用 Parse() 方法将字符串转换为 double 型数字
                            double color_x = threshold_Ref.Color1_x - double.Parse(numbers1[0]);
                            double color_y = threshold_Ref.Color1_y - double.Parse(numbers1[1]);
                            richTextBox1.Text = String.Concat(richTextBox1.Text, "COLOR1:\r\n", buffer1.ToString(), "  ");
                            richTextBox1.Text = String.Concat(richTextBox1.Text, color_x.ToString("F4"), " ", color_y.ToString("F4"), "\r\n");
                            if (color_x < 0.01 && color_x > -0.01 && color_y < 0.01 && color_y > -0.01 && color_check == 0)
                            {
                                color_check1 = 1;
                            }
                        }
                        else
                        {
                            MessageBox.Show("收光器2没有收到测试色颜色1!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                            return;
                        }
                    }

                }
                if (j == 1)
                {
                    Lin_MasterWrite(GetUartCmd(ColorName.Color2));
                    Thread.Sleep(100);
                    Lin_MasterWrite(GetUartCmd(ColorName.Color2));
                    Thread.Sleep(Lit_wait_time);
                    resp = FeasaCom_Send(portNumber, "CAPTURE300", buffer);
                    resp = FeasaCom_Send(portNumber, "GETXY", buffer);
                    resp = FeasaCom_Send(portNumber1, "CAPTURE300", buffer1);
                    resp = FeasaCom_Send(portNumber1, "GETXY", buffer1);
                    string[] numbers = buffer.ToString().Split(' '); // 使用空格字符拆分字符串
                    string[] numbers1 = buffer1.ToString().Split(' '); // 使用空格字符拆分字符串
                    if (flag)
                    {
                        if (numbers.Length == 2 && numbers[0] != "ERROR:")
                        {
                            // 使用 Parse() 方法将字符串转换为 double 型数字
                            double color_x = threshold_Ref.Color2_x - double.Parse(numbers[0]);
                            double color_y = threshold_Ref.Color2_y - double.Parse(numbers[1]);
                            txtLog.Text = String.Concat(txtLog.Text, "COLOR2:\r\n", buffer.ToString(), "  ");
                            txtLog.Text = String.Concat(txtLog.Text, color_x.ToString("F4"), " ", color_y.ToString("F4"), "\r\n");
                            txtLog.ScrollToCaret();
                            if (color_x < 0.01 && color_x > -0.01 && color_y < 0.01 && color_y > -0.01 && color_check == 1)
                            {
                                color_check = 2;
                            }
                        }
                        else
                        {
                            MessageBox.Show("收光器1没有收到测试色颜色2!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                            return;
                        }
                    }
                    if (flag1)
                    {
                        if (numbers1.Length == 2 && numbers1[0] != "ERROR:")
                        {
                            // 使用 Parse() 方法将字符串转换为 double 型数字
                            double color_x = threshold_Ref.Color2_x - double.Parse(numbers1[0]);
                            double color_y = threshold_Ref.Color2_y - double.Parse(numbers1[1]);
                            richTextBox1.Text = String.Concat(richTextBox1.Text, "COLOR2:\r\n", buffer1.ToString(), "  ");
                            richTextBox1.Text = String.Concat(richTextBox1.Text, color_x.ToString("F4"), " ", color_y.ToString("F4"), "\r\n");
                            richTextBox1.ScrollToCaret();
                            if (color_x < 0.01 && color_x > -0.01 && color_y < 0.01 && color_y > -0.01 && color_check1 == 1)
                            {
                                color_check1 = 2;
                            }
                        }
                        else
                        {
                            MessageBox.Show("收光器2没有收到测试色颜色2!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                            return;
                        }
                    }


                }
                if (j == 2)
                {
                    Lin_MasterWrite(GetUartCmd(ColorName.Color3));
                    Thread.Sleep(300);
                    Lin_MasterWrite(GetUartCmd(ColorName.Color3));
                    Thread.Sleep(Lit_wait_time);
                    resp = FeasaCom_Send(portNumber, "CAPTURE300", buffer);
                    resp = FeasaCom_Send(portNumber, "GETXY", buffer);
                    resp = FeasaCom_Send(portNumber1, "CAPTURE300", buffer1);
                    resp = FeasaCom_Send(portNumber1, "GETXY", buffer1);
                    string[] numbers = buffer.ToString().Split(' '); // 使用空格字符拆分字符串
                    string[] numbers1 = buffer1.ToString().Split(' '); // 使用空格字符拆分字符串
                    if (flag)
                    {
                        if (numbers.Length == 2 && numbers[0] != "ERROR:")
                        {
                            // 使用 Parse() 方法将字符串转换为 double 型数字
                            double color_x = threshold_Ref.Color3_x - double.Parse(numbers[0]);
                            double color_y = threshold_Ref.Color3_y - double.Parse(numbers[1]);
                            txtLog.Text = String.Concat(txtLog.Text, "COLOR3:\r\n", buffer.ToString(), "  ");
                            txtLog.Text = String.Concat(txtLog.Text, color_x.ToString("F4"), " ", color_y.ToString("F4"), "\r\n");
                            txtLog.ScrollToCaret();
                            if (color_x < 0.01 && color_x > -0.01 && color_y < 0.01 && color_y > -0.01 && color_check == 2)
                            {
                                color_check = 3;
                            }
                        }
                        else
                        {
                            MessageBox.Show("收光器1没有收到测试色颜色3!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                            return;
                        }
                    }
                    if (flag1)
                    {
                        if (numbers1.Length == 2 && numbers1[0] != "ERROR:")
                        {
                            // 使用 Parse() 方法将字符串转换为 double 型数字
                            double color_x = threshold_Ref.Color3_x - double.Parse(numbers1[0]);
                            double color_y = threshold_Ref.Color3_y - double.Parse(numbers1[1]);
                            richTextBox1.Text = String.Concat(richTextBox1.Text, "COLOR3:\r\n", buffer1.ToString(), "  ");
                            richTextBox1.Text = String.Concat(richTextBox1.Text, color_x.ToString("F4"), " ", color_y.ToString("F4"), "\r\n");
                            richTextBox1.ScrollToCaret();
                            if (color_x < 0.01 && color_x > -0.01 && color_y < 0.01 && color_y > -0.01 && color_check1 == 2)
                            {
                                color_check1 = 3;
                            }
                        }
                        else
                        {
                            MessageBox.Show("收光器2没有收到测试色颜色3!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                            return;
                        }
                    }
                }
                if (j == 3)
                {
                    Lin_MasterWrite(GetUartCmd(ColorName.Color4));
                    Thread.Sleep(300);
                    Lin_MasterWrite(GetUartCmd(ColorName.Color4));
                    Thread.Sleep(Lit_wait_time);
                    resp = FeasaCom_Send(portNumber, "CAPTURE300", buffer);
                    resp = FeasaCom_Send(portNumber, "GETXY", buffer);
                    resp = FeasaCom_Send(portNumber1, "CAPTURE300", buffer1);
                    resp = FeasaCom_Send(portNumber1, "GETXY", buffer1);
                    string[] numbers = buffer.ToString().Split(' '); // 使用空格字符拆分字符串
                    string[] numbers1 = buffer1.ToString().Split(' '); // 使用空格字符拆分字符串
                    if (flag)
                    {
                        if (numbers.Length == 2 && numbers[0] != "ERROR:")
                        {
                            // 使用 Parse() 方法将字符串转换为 double 型数字
                            double color_x = threshold_Ref.Color4_x - double.Parse(numbers[0]);
                            double color_y = threshold_Ref.Color4_y - double.Parse(numbers[1]);
                            txtLog.Text = String.Concat(txtLog.Text, "COLOR4:\r\n", buffer.ToString(), "  ");
                            txtLog.Text = String.Concat(txtLog.Text, color_x.ToString("F4"), " ", color_y.ToString("F4"), "\r\n");
                            txtLog.ScrollToCaret();
                            if (color_x < 0.01 && color_x > -0.01 && color_y < 0.01 && color_y > -0.01 && color_check == 3)
                            {
                                color_check = 4;
                            }
                        }
                        else
                        {
                            MessageBox.Show("收光器1没有收到测试色颜色4!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                            return;
                        }
                    }
                    if (flag1)
                    {
                        if (numbers1.Length == 2 && numbers1[0] != "ERROR:")
                        {
                            // 使用 Parse() 方法将字符串转换为 double 型数字
                            double color_x = threshold_Ref.Color4_x - double.Parse(numbers1[0]);
                            double color_y = threshold_Ref.Color4_y - double.Parse(numbers1[1]);
                            richTextBox1.Text = String.Concat(richTextBox1.Text, "COLOR4:\r\n", buffer1.ToString(), "  ");
                            richTextBox1.Text = String.Concat(richTextBox1.Text, color_x.ToString("F4"), " ", color_y.ToString("F4"), "\r\n");
                            richTextBox1.ScrollToCaret();
                            if (color_x < 0.01 && color_x > -0.01 && color_y < 0.01 && color_y > -0.01 && color_check1 == 3)
                            {
                                color_check1 = 4;
                            }
                        }
                        else
                        {
                            MessageBox.Show("收光器2没有收到测试色颜色4!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                            return;
                        }
                    }
                }
                if (j == 4)
                {
                    Lin_MasterWrite(GetUartCmd(ColorName.Color5));
                    Thread.Sleep(300);
                    Lin_MasterWrite(GetUartCmd(ColorName.Color5));
                    Thread.Sleep(Lit_wait_time);
                    resp = FeasaCom_Send(portNumber, "CAPTURE300", buffer);
                    resp = FeasaCom_Send(portNumber, "GETXY", buffer);
                    resp = FeasaCom_Send(portNumber1, "CAPTURE300", buffer1);
                    resp = FeasaCom_Send(portNumber1, "GETXY", buffer1);
                    string[] numbers = buffer.ToString().Split(' '); // 使用空格字符拆分字符串
                    string[] numbers1 = buffer1.ToString().Split(' '); // 使用空格字符拆分字符串
                    if (flag)
                    {
                        if (numbers.Length == 2 && numbers[0] != "ERROR:")
                        {
                            // 使用 Parse() 方法将字符串转换为 double 型数字
                            double color_x = threshold_Ref.Color5_x - double.Parse(numbers[0]);
                            double color_y = threshold_Ref.Color5_y - double.Parse(numbers[1]);
                            txtLog.Text = String.Concat(txtLog.Text, "COLOR5:\r\n", buffer.ToString(), "  ");
                            txtLog.Text = String.Concat(txtLog.Text, color_x.ToString("F4"), " ", color_y.ToString("F4"), "\r\n");
                            txtLog.ScrollToCaret();
                            if (color_x < 0.01 && color_x > -0.01 && color_y < 0.01 && color_y > -0.01 && color_check == 4)
                            {
                                color_check = 5;
                            }
                        }
                        else
                        {
                            MessageBox.Show("收光器1没有收到测试色颜色5!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                            return;
                        }
                    }
                    if (flag1)
                    {
                        if (numbers1.Length == 2 && numbers1[0] != "ERROR:")
                        {
                            // 使用 Parse() 方法将字符串转换为 double 型数字
                            double color_x = threshold_Ref.Color5_x - double.Parse(numbers1[0]);
                            double color_y = threshold_Ref.Color5_y - double.Parse(numbers1[1]);
                            richTextBox1.Text = String.Concat(richTextBox1.Text, "COLOR5:\r\n", buffer1.ToString(), "  ");
                            richTextBox1.Text = String.Concat(richTextBox1.Text, color_x.ToString("F4"), " ", color_y.ToString("F4"), "\r\n");
                            richTextBox1.ScrollToCaret();
                            if (color_x < 0.01 && color_x > -0.01 && color_y < 0.01 && color_y > -0.01 && color_check1 == 4)
                            {
                                color_check1 = 5;
                            }
                        }
                        else
                        {
                            MessageBox.Show("收光器2没有收到测试色颜色5!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                            return;
                        }
                    }
                }

            }
            if (flag)
            {
                if (color_check == 5)
                {
                    color_check = 0;
                    cmdRead.BackColor = Color.Green; // 设置为绿色背景
                    cmdRead.Text = "Pass";
                    string fileName1 = textBox3.Text.Trim();
                    UpdateProductionData();

                    try
                    {
                        // 自动添加 .rtf 扩展名（可选）
                        if (!Path.HasExtension(fileName1))
                        {
                            fileName1 += ".txt";
                        }
                        DateTime now = DateTime.Now;
                        Console.WriteLine(now); // 输出当前日期和时间
                        txtLog.Text = String.Concat(txtLog.Text, "Time:", now, "\r\n");

                        // 获取当前应用程序所在目录的路径
                        string appDirectory = Application.StartupPath;
                        // 构建 log 文件夹的完整路径
                        string logDirectory = Path.Combine(appDirectory, "NDLB_log");
                        // 自动创建 log 文件夹（如果不存在）
                        Directory.CreateDirectory(logDirectory);
                        // 构建完整文件路径
                        string fullPath = Path.Combine(logDirectory, fileName1);
                        if (File.Exists(fullPath))
                        {
                            DialogResult result = MessageBox.Show("文件已存在，是否覆盖？", "确认", MessageBoxButtons.YesNo);
                            if (result != DialogResult.Yes) ;
                        }
                        // 使用File.WriteAllText指定UTF-8编码
                        File.WriteAllText(fullPath, txtLog.Text, Encoding.UTF8);
                        MessageBox.Show("保存成功！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show($"保存失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }

                }
                else
                {
                    color_check = 0;
                    cmdRead.BackColor = Color.Red; // 设置为红色背景
                    cmdRead.Text = "Fail";
                }
            }
            if (flag1)
            {
                if (color_check1 == 5)
                {
                    color_check1 = 0;
                    button1.BackColor = Color.Green; // 设置为绿色背景
                    button1.Text = "Pass";
                    string fileName2 = textBox4.Text.Trim();
                    UpdateProductionData();

                    try
                    {
                        // 自动添加 .rtf 扩展名（可选）
                        if (!Path.HasExtension(fileName2))
                        {
                            fileName2 += ".txt";
                        }
                        DateTime now = DateTime.Now;
                        Console.WriteLine(now); // 输出当前日期和时间
                        richTextBox1.Text = String.Concat(richTextBox1.Text, "Time:", now, "\r\n");

                        // 获取当前应用程序所在目录的路径
                        string appDirectory = Application.StartupPath;
                        // 构建 log 文件夹的完整路径
                        string logDirectory = Path.Combine(appDirectory, "NDLB_log");
                        // 自动创建 log 文件夹（如果不存在）
                        Directory.CreateDirectory(logDirectory);
                        // 构建完整文件路径
                        string fullPath = Path.Combine(logDirectory, fileName2);
                        if (File.Exists(fullPath))
                        {
                            DialogResult result = MessageBox.Show("文件已存在，是否覆盖？", "确认", MessageBoxButtons.YesNo);
                            if (result != DialogResult.Yes) return;
                        }
                        // 使用File.WriteAllText指定UTF-8编码
                        File.WriteAllText(fullPath, richTextBox1.Text, Encoding.UTF8);
                        MessageBox.Show("保存成功！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show($"保存失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
                else
                {
                    color_check = 0;
                    button1.BackColor = Color.Red; // 设置为红色背景
                    button1.Text = "Fail";
                }
            }
            end_flag = 1;
            Lin_MasterWrite(param2);
            Lin_MasterWrite(param5);
            Lin_MasterWrite(param2);
            Lin_MasterWrite(param5);
        }

        private void numericWavelengthResolution_ValueChanged(object sender, EventArgs e)
        {

        }

        private void Lin_MasterWrite(byte[] DataBuffer)
        {
            Lin_MasterWrite0(DataBuffer);
            Lin_MasterWrite1(DataBuffer);
        }

        private void Lin_MasterWrite0(byte[] DataBuffer)
        {
            byte[] temp = new byte[DataBuffer.Length - 1];
            for (int i = 1; i < DataBuffer.Length; i++)
            {
                temp[i - 1] = DataBuffer[i];
            }
            Lin_MasterWrite0(DataBuffer[0], temp);
        }
        private void Lin_MasterWrite0(byte pid, byte[] DataBuffer)
        {
            Byte checkType = USB2LIN_EX.LIN_EX_CHECK_STD;
            if (pid == 0x3c) checkType = USB2LIN_EX.LIN_EX_CHECK_STD;
            else checkType = USB2LIN_EX.LIN_EX_CHECK_EXT;
            //唤醒设备
            var ret = USB2LIN_EX.LIN_EX_MasterWrite(DevHandle, 0, pid, DataBuffer, (byte)DataBuffer.Length, checkType);
            if (ret != USB2LIN_EX.LIN_EX_SUCCESS)
            {
                Console.WriteLine("Write LIN failed!");
                return;
            }
            else
            {
                Console.WriteLine("Write LIN Success!");
            }
        }

        private void Lin_MasterWrite1(byte[] DataBuffer)
        {
            byte[] temp = new byte[DataBuffer.Length - 1];
            for (int i = 1; i < DataBuffer.Length; i++)
            {
                temp[i - 1] = DataBuffer[i];
            }
            Lin_MasterWrite1(DataBuffer[0], temp);
        }
        private void Lin_MasterWrite1(byte pid, byte[] DataBuffer)
        {
            Byte checkType = USB2LIN_EX.LIN_EX_CHECK_STD;
            if (pid == 0x3c) checkType = USB2LIN_EX.LIN_EX_CHECK_STD;
            else checkType = USB2LIN_EX.LIN_EX_CHECK_EXT;
            //唤醒设备
            var ret = USB2LIN_EX.LIN_EX_MasterWrite(DevHandle, 1, pid, DataBuffer, (byte)DataBuffer.Length, checkType);
            if (ret != USB2LIN_EX.LIN_EX_SUCCESS)
            {
                Console.WriteLine("Write LIN failed!");
                return;
            }
            else
            {
                Console.WriteLine("Write LIN Success!");
            }
        }

        private void zedGraphControl1_Load(object sender, EventArgs e)
        {

        }

        private void Darkcalibration_Click(object sender, EventArgs e)
        {
            if (flag)
            {
                cmdRead.Text = "正在进行暗校准...";
                if (fease_connect_state == 0)
                {
                    MessageBox.Show("请先连接光谱仪");
                }
                else
                {
                    if (FeasaCom_SpectrometerDark(portNumber, 0, 0, 0) == 1)
                    {
                        MessageBox.Show("暗校准完成");

                        cmdRead.Text = "请选择标定位置";
                    }
                    else
                    {
                        MessageBox.Show("暗校准失败");
                    }
                }
            }
            if (flag1)
            {
                button1.Text = "正在进行暗校准...";
                if (fease_connect_state1 == 0)
                {
                    MessageBox.Show("请先连接光谱仪");
                }
                else
                {
                    if (FeasaCom_SpectrometerDark(portNumber1, 0, 0, 0) == 1)
                    {
                        MessageBox.Show("暗校准完成");
                        button1.Text = "请选择标定位置";
                    }
                    else
                    {
                        MessageBox.Show("暗校准失败");
                    }
                }
            }
        }

        private void Feaseconnect_Click(object sender, EventArgs e)
        {
            FeasaCom_EnumPorts();
            toomos_connect_state = Toomos_connect();
            if (!toomos_connect_state)
            {
                return;
            }
            if (flag)
            {
                portNumber = Convert.ToInt32(lstPorts.Items[lstPorts.SelectedIndex]);
                fease_connect_state = FeasaCom_Open(portNumber, "AUTO");
                if (fease_connect_state == 1)
                {
                    MessageBox.Show("光谱仪1连接成功");
                    cmdRead.Text = "请进行暗校准";
                }
                else
                {
                    MessageBox.Show("光谱仪1连接失败");
                }
            }
            else 
            {
                cmdRead.Text = "";
            }

            if (flag1)
            {
                portNumber1 = Convert.ToInt32(lstPorts1.Items[lstPorts1.SelectedIndex]);
                FeasaCom_EnumPorts();
                fease_connect_state1 = FeasaCom_Open(portNumber1, "AUTO");
                if (fease_connect_state1 == 1)
                {
                    MessageBox.Show("光谱仪2连接成功");
                    button1.Text = "请进行暗校准";
                    return;
                }
                else
                {
                    MessageBox.Show("光谱仪2连接失败");
                    return;
                }
            }
            else
            { 
                button1.Text = ""; 
            }
        }
        bool Toomos_connect()
        {
            Int32 DevNum, ret,ret1 = 0;
            byte state;
            Int32[] DevHandles = new Int32[20];
            USB_DEVICE.DEVICE_INFO DevInfo = new USB_DEVICE.DEVICE_INFO();
            string dllFilePath = "USB2XXX.dll";
            if (!File.Exists(dllFilePath))
            {
                Console.WriteLine("请先将USB2XXX.dll和libusb-1.0.dll文件复制到exe程序文件输出目录下!");
                Console.WriteLine("dll文件在‘usb2can_lin_pwm_example/sdk/libs/windows’目录下！");
                Console.WriteLine("程序是32位的就复制‘x86’目录下文件，程序是64位的就复制‘x86_64’目录下文件！");
                return false;
            }
            //扫描查找设备
            DevNum = USB_DEVICE.USB_ScanDevice(DevHandles);
            if (DevNum > 2)
            {
                MessageBox.Show("只支持一个图莫斯驱动。");
                return false;
            }
            if (DevNum == 0)
            {
                MessageBox.Show("没接上图莫斯驱动。");
                return false;
            }
            DevHandle = DevHandles[0];
            //打开设备
            state = USB_DEVICE.USB_OpenDevice(DevHandle);
            if (state==0)
            {
                Console.WriteLine("Open device error!");
                return false;
            }
            else
            {
                Console.WriteLine("Open device success!");
            }
            //获取固件信息
            StringBuilder FuncStr = new StringBuilder(256);
            state = USB_DEVICE.DEV_GetDeviceInfo(DevHandle, ref DevInfo, FuncStr);
            if (state==0)
            {
                Console.WriteLine("Get device infomation error!");
                return false;
            }
            else
            {
                Console.WriteLine("Firmware Info:");
                Console.WriteLine("    Name:" + Encoding.Default.GetString(DevInfo.FirmwareName));
                Console.WriteLine("    Build Date:" + Encoding.Default.GetString(DevInfo.BuildDate));
                Console.WriteLine("    Firmware Version:v{0}.{1}.{2}", (DevInfo.FirmwareVersion >> 24) & 0xFF, (DevInfo.FirmwareVersion >> 16) & 0xFF, DevInfo.FirmwareVersion & 0xFFFF);
                Console.WriteLine("    Hardware Version:v{0}.{1}.{2}", (DevInfo.HardwareVersion >> 24) & 0xFF, (DevInfo.HardwareVersion >> 16) & 0xFF, DevInfo.HardwareVersion & 0xFFFF);
                Console.WriteLine("    Functions:" + DevInfo.Functions.ToString("X8"));
                Console.WriteLine("    Functions String:" + FuncStr);
            }
            //初始化配置LIN1
            ret = USB2LIN_EX.LIN_EX_Init(DevHandle, 0, 19200, USB2LIN_EX.LIN_EX_MASTER);//初始化为主机
            ret1 = USB2LIN_EX.LIN_EX_Init(DevHandle, 1, 19200, USB2LIN_EX.LIN_EX_MASTER);//初始化为主机
            if ((ret& ret1) != USB2LIN_EX.LIN_EX_SUCCESS)
            {
                Console.WriteLine("Config LIN failed!");
                MessageBox.Show("LIN打开失败", "提示");
                return false;
            }
            else
            {
                Console.WriteLine("Config LIN Success!");
                return true;
            }
        }

        // 文本变化时自动触发
        private void TextBox1_TextChanged(object sender, EventArgs e)
        {
            string input = textBox1.Text;

            // 仅在输入长度匹配目标时触发
            if (input.Length == 35)
            {
                ExtractAndDisplayCode(input);
            }
            else
            {
                textBox3.Text = ""; // 非目标长度时清空结果
            }
        }

        // 提取并显示编码
        private void ExtractAndDisplayCode(string input)
        {
            Match match = Regex.Match(input, @"(\d{14})$");
            if (match.Success)
            {
                textBox3.Text = match.Value;
                textBox3.BackColor = System.Drawing.Color.LightGreen;
                if (flag1)
                {
                    textBox2.Clear();
                    textBox2.Focus(); // 操作完成后重新聚焦
                    button1.Text = "请扫描通道2二维码";
                }
                else
                {
                    cmdRead.Text = "请点击按钮开始标定"; 
                }
                
            }
            else
            {
                textBox3.Text = "未找到有效编码";
                textBox3.BackColor = System.Drawing.Color.LightPink;
            }
        }
        // 文本变化时自动触发
        private void TextBox2_TextChanged(object sender, EventArgs e)
        {
            string input = textBox2.Text;

            // 仅在输入长度匹配目标时触发
            if (input.Length == 35)
            {
                ExtractAndDisplayCode2(input);
                //Mouse.OverrideCursor = Cursors.None;

                //// 恢复光标
                //Mouse.OverrideCursor = null; // 或者设置为其他光标样式，如 Cursors.Arrow
            }
            else
            {
                textBox4.Text = ""; // 非目标长度时清空结果
            }
        }

        // 提取并显示编码
        private void ExtractAndDisplayCode2(string input)
        {
            Match match1 = Regex.Match(input, @"(\d{14})$");
            if (match1.Success)
            {
                textBox4.Text = match1.Value;
                textBox4.BackColor = System.Drawing.Color.LightGreen;
                button1.Text = "请点击按钮开始标定";
            }
            else
            {
                textBox4.Text = "未找到有效编码";
                textBox4.BackColor = System.Drawing.Color.LightPink;
            }
        }

        private void MainWindow_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
               
                if (end_flag == 1)
                {
                    end_flag = 0;
                    textBox1.Text = ""; // 清空textBox1显示
                    textBox2.Text = ""; // 清空textBox2显示
                    textBox3.Text = ""; // 清空textBox3显示
                    textBox4.Text = ""; // 清空textBox4显示
                    textBox3.BackColor = System.Drawing.Color.White;
                    textBox4.BackColor = System.Drawing.Color.White;
                    cmdRead.BackColor = Color.White; // 设置为白色背景
                    button1.BackColor = Color.White; // 设置为白色背景
                    txtLog.Text = ""; // 清空cmdRead显示
                    richTextBox1.Text = ""; // 清空button1显示

                    if (flag)
                    {
                        textBox1.Clear();
                        textBox1.Focus(); // 操作完成后重新聚焦
                        cmdRead.Text = "请扫描通道1二维码";
                    }
                    else
                    {
                        if(flag1)
                        {
                            textBox2.Clear();
                            textBox2.Focus(); // 操作完成后重新聚焦
                            button1.Text = "请扫描通道2二维码";
                        }
                        
                    }
                   
                }
                else
                {
                    if (flag)
                    {
                        cmdRead.BackColor = Color.White; // 设置为白色背景
                        cmdRead.Text = "Testing...";
                    }
                    if (flag1)
                    {
                        button1.BackColor = Color.White; // 设置为白色背景
                        button1.Text = "Testing...";
                    }
                    CmdRead_Click(sender, e); // 触发按钮点击事件
                }
            }
        }

        private void CRC(byte[] param)
        {
            int lin_crc = 0;
            if (param[0] == 0x3C)
            {
                lin_crc = param[1];
            }
            else
            {
                lin_crc = param[0] + param[1];
            }
            if (lin_crc > 0xFF)
            {
                lin_crc -= 0x100;
                lin_crc++;
            }
            for (int i = 2; i < 9; i++)
            {
                lin_crc += param[i];
                if (lin_crc > 0xFF)
                {
                    lin_crc -= 0x100;
                    lin_crc++;
                }
            }
            lin_crc = 0xFF - lin_crc;

            param[9] = (byte)lin_crc;
        }
        private void Txt_ReadView()
        {
            string filePath = Path.Combine(
                AppDomain.CurrentDomain.SetupInformation.ApplicationBase,
                "NDLB_NAD_DIM.txt"
            );
            
            NDLB_DIM.Clear();
            NDLB_NAD.Clear();

            try
            {
                // 读取所有行
                var lines = File.ReadAllLines(filePath);
                // 1. 首先处理第一行的版本号
                if (lines.Length == 0)
                    throw new Exception("文件为空");
                string firstLine = lines[0];
                if (firstLine.StartsWith("Version:"))
                {
                    string versionPart = firstLine.Split(':')[1].Trim();
                    string[] versionParts = versionPart.Split('.');

                    if (versionParts.Length == 6)
                    {
                        int D_major = int.Parse(versionParts[0]);
                        int D_minor = int.Parse(versionParts[1]);
                        int D_patch = int.Parse(versionParts[2]);
                        int S_major = int.Parse(versionParts[3]);
                        int S_minor = int.Parse(versionParts[4]);
                        int S_patch = int.Parse(versionParts[5]);

                        version1 = D_major * 10000 + D_minor * 100 + D_patch;
                        version2 = S_major * 10000 + S_minor * 100 + S_patch;
                    }
                    else
                    {
                        Console.WriteLine("版本号格式不正确，应为 XX.XX.XX");
                    }
                }
                string secondLine = lines[1];
                if (secondLine.StartsWith("Own Version:"))
                {
                    string versionPart = secondLine.Split(':')[1].Trim();
                    Own_version = int.Parse(versionPart);
                }
                else
                {
                    Console.WriteLine("OWN版本号格式不正确，应为 XX.XX.XX");
                }
                string thridLine = lines[2];
                if (thridLine.StartsWith("Lin Sign:"))
                {
                    string versionPart = thridLine.Split(':')[1].Trim();
                    if (byte.TryParse(versionPart.Trim(), NumberStyles.HexNumber, null, out byte nadValue))
                    {
                        Lin_sign = nadValue;
                    }
                }
                else
                {
                    Console.WriteLine("OWN版本号格式不正确，应为 XX.XX.XX");
                }
                // 2. 处理剩余行的数据（跳过第一行）
                for (int i = 2; i < lines.Length; i++)
                {
                    string line = lines[i].Trim();
                    if (string.IsNullOrWhiteSpace(line))
                        continue;

                    string[] parts = line.Split(',');
                    if (parts.Length == 2)
                    {
                        // 处理亮度系数
                        if (byte.TryParse(parts[0].Trim(), out byte dimValue))
                        {
                            NDLB_DIM.Add(dimValue);
                        }
                        // 处理NAD（十六进制）
                        if (byte.TryParse(parts[1].Trim(), NumberStyles.HexNumber, null, out byte nadValue))
                        {
                            NDLB_NAD.Add(nadValue);
                        }
                    }
                }
            }
            catch (FileNotFoundException)
            {
                MessageBox.Show("文件未找到: " + filePath);
            }
            catch (Exception ex)
            {
                MessageBox.Show("读取文件时出错: " + ex.Message);
            }
        }

        public void UpdateProductionData()
        {
            const string filePath = "NDLB_Today_Number.txt";
            string dateStr = DateTime.Today.ToString("yyyy-MM-dd");

            try
            {
                // 1. 处理文件不存在的情况
                if (!File.Exists(filePath))
                {
                    SafeWriteAllText(filePath, $"{dateStr},1");
                    UpdateUI(dateStr, "1");
                    return;
                }

                // 2. 读取文件内容
                List<string> lines = SafeReadAllLines(filePath);

                // 3. 处理数据逻辑
                ProcessData(ref lines, dateStr);

                // 4. 写入文件
                SafeWriteAllLines(filePath, lines);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"操作失败: {ex.Message}\n建议关闭其他可能使用此文件的程序",
                              "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        #region 安全文件操作方法

        private List<string> SafeReadAllLines(string path)
        {
            const int maxRetry = 3;
            int retryCount = 0;

            while (retryCount < maxRetry)
            {
                try
                {
                    return new List<string>(File.ReadAllLines(path));
                }
                catch (IOException)
                {
                    retryCount++;
                    if (retryCount >= maxRetry) throw;
                    Thread.Sleep(100 * retryCount);
                }
            }
            return new List<string>();
        }

        private void SafeWriteAllText(string path, string content)
        {
            using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None))
            using (var writer = new StreamWriter(fs))
            {
                writer.Write(content);
            }
        }

        private void SafeWriteAllLines(string path, List<string> lines)
        {
            string tempPath = Path.Combine(Path.GetDirectoryName(path),
                                         Guid.NewGuid().ToString() + ".tmp");

            // 先写入临时文件
            File.WriteAllLines(tempPath, lines);

            // 原子化替换
            try
            {
                File.Replace(tempPath, path, null, true);
            }
            catch
            {
                // 如果替换失败，尝试直接覆盖
                if (File.Exists(tempPath))
                {
                    File.Copy(tempPath, path, true);
                    File.Delete(tempPath);
                }
                throw;
            }
        }

        #endregion

        private void ProcessData(ref List<string> lines, string currentDate)
        {
            if (lines.Count == 0)
            {
                lines.Add($"{currentDate},1");
                UpdateUI(currentDate, "1");
                return;
            }

            var lastEntry = lines[lines.Count - 1].Split(',');

            if (lastEntry.Length >= 2 && lastEntry[0] == currentDate)
            {
                currentnum = int.TryParse(lastEntry[1], out int num) ? num + 1 : 1;
                lines[lines.Count - 1] = $"{currentDate},{currentnum}";
                UpdateUI(currentDate, currentnum.ToString());
            }
            else
            {
                lines.Add($"{currentDate},1");
                UpdateUI(currentDate, "1");
            }
        }

        private void UpdateUI(string date, string production)
        {
            if (textBox5.InvokeRequired || textBox6.InvokeRequired)
            {
                this.Invoke(new Action(() =>
                {
                    textBox5.Text = date;
                    textBox6.Text = production;
                }));
            }
            else
            {
                textBox5.Text = date;
                textBox6.Text = production;
            }
        }
        // 更新UI控件显示

        // 文件操作锁
        private static readonly object fileLock = new object();

        // lstPorts 的选中事件处理器
        private void LstPorts_SelectedIndexChanged(object sender, EventArgs e)
        {
            // 如果选中了端口
            if (lstPorts.SelectedIndex != -1)
            {
                flag = true; // 设置标志变量为1
                cmdRead.Text = "请连接光谱仪1";
                // 在 lstPorts1 中移除选中的端口
                if (lstPorts1.Items.Contains(lstPorts.SelectedItem))
                {
                    lstPorts1.Items.Remove(lstPorts.SelectedItem);
                }
            }
            else
            {
                flag = false; // 如果没有选中端口，标志变量置为0
            }
        }

        // lstPorts1 的选中事件处理器
        private void LstPorts1_SelectedIndexChanged(object sender, EventArgs e)
        {
            // 如果选中了端口
            if (lstPorts1.SelectedIndex != -1)
            {
                flag1 = true; // 设置标志变量为1
                button1.Text = "请连接光谱仪2";
                // 在 lstPorts 中移除选中的端口
                if (lstPorts.Items.Contains(lstPorts1.SelectedItem))
                {
                    lstPorts.Items.Remove(lstPorts1.SelectedItem);
                }
            }
            else
            {
                flag1 = false; // 如果没有选中端口，标志变量置为0
            }
        }

        internal class Threshold_Reference
        {
            public readonly double R_x = 0;
            public readonly double R_y = 0;
            public readonly double R_z = 0;

            public readonly double G_x = 0;
            public readonly double G_y = 0;
            public readonly double G_z = 0;

            public readonly double B_x = 0;
            public readonly double B_y = 0;
            public readonly double B_z = 0;

            public readonly double Color1_x = 0.313;
            public readonly double Color1_y = 0.329;
            public readonly double Color1_z = 0;

            public readonly double Color2_x = 0.245;
            public readonly double Color2_y = 0.286;
            public readonly double Color2_z = 0;

            public readonly double Color3_x = 0.474;
            public readonly double Color3_y = 0.351;
            public readonly double Color3_z = 0;

            public readonly double Color4_x = 0.229;
            public readonly double Color4_y = 0.173;
            public readonly double Color4_z = 0;

            public readonly double Color5_x = 0.440;
            public readonly double Color5_y = 0.413;
            public readonly double Color5_z = 0;

        }
        private void CRC2(byte[] param)
        {
            int lin_crc = 0;

            lin_crc = param[0]; //+ param[1];
            for (int i = 2; i < 9; i++)
            {
                lin_crc += param[i];
                if (lin_crc > 0xFF)
                {
                    lin_crc -= 0x100;
                    lin_crc++;
                }
            }
            lin_crc = 0xFF - lin_crc;

            param[9] = (byte)lin_crc;
        }
        private void GroupBox2_Enter(object sender, EventArgs e)
        {

        }


        private void button1_Click(object sender, EventArgs e)
        {

        }

        private void label2_Click(object sender, EventArgs e)
        {

        }

        private void numericUpDown1_ValueChanged(object sender, EventArgs e)
        {

        }

        private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {

        }

        private void dataGridView1_CellContentClick_1(object sender, DataGridViewCellEventArgs e)
        {

        }

        private void Label1_Click(object sender, EventArgs e)
        {

        }

        private void label3_Click(object sender, EventArgs e)
        {

        }

        private void txtLog_TextChanged(object sender, EventArgs e)
        {

        }

        private void label4_Click(object sender, EventArgs e)
        {

        }
        private void treeView1_DrawNode(object sender, DrawTreeNodeEventArgs e)
        {
            // 如果节点被选中
            if ((e.State & TreeNodeStates.Selected) != 0)
            {
                // 自定义选中高光颜色（例如：蓝色背景，白色文字）
                e.Graphics.FillRectangle(Brushes.DarkBlue, e.Bounds); // 设置选中背景色
                Font nodeFont = e.Node.NodeFont ?? location_choose.Font;
                e.Graphics.DrawString(e.Node.Text, nodeFont, Brushes.White, e.Bounds); // 设置选中文本颜色
            }
            else
            {
                // 绘制默认样式
                e.DrawDefault = true;
            }
        }

        private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
        {
            TreeNode location_choose = e.Node;
            if (location_choose != null)
            {
                // 例如，根据节点的文本执行不同的操作
                switch (location_choose.Text)
                {
                    case "IP左":
                        NDLB_CURRENT_NAD = (byte)NDLB_NAD[0];
                        NDLB_CURRENT_DIM = (byte)NDLB_DIM[0];
                        PID = 0x10;
                        break;
                    case "左前门":
                        NDLB_CURRENT_NAD = (byte)NDLB_NAD[1];
                        NDLB_CURRENT_DIM = (byte)NDLB_DIM[1];
                        PID = 0x10;
                        break;
                    case "IP右":
                        NDLB_CURRENT_NAD = (byte)NDLB_NAD[2];
                        NDLB_CURRENT_DIM = (byte)NDLB_DIM[2];
                        PID = 0x11;
                        break;
                    case "右前门":
                        NDLB_CURRENT_NAD = (byte)NDLB_NAD[3];
                        NDLB_CURRENT_DIM = (byte)NDLB_DIM[3];
                        PID = 0x11;
                        break;
                    case "左后门":
                        NDLB_CURRENT_NAD = (byte)NDLB_NAD[4];
                        NDLB_CURRENT_DIM = (byte)NDLB_DIM[4];
                        PID = 0x12;
                        break;
                    case "右后门":
                        NDLB_CURRENT_NAD = (byte)NDLB_NAD[5];
                        NDLB_CURRENT_DIM = (byte)NDLB_DIM[5];
                        PID = 0x13;
                        break;
                    case "CNSL":
                        NDLB_CURRENT_NAD = (byte)NDLB_NAD[6];
                        NDLB_CURRENT_DIM = (byte)NDLB_DIM[6];
                        PID = 0x14;
                        break;
                    case "IP中":
                        NDLB_CURRENT_NAD = (byte)NDLB_NAD[7];
                        NDLB_CURRENT_DIM = (byte)NDLB_DIM[7];
                        PID = 0x14;
                        break;
                    default:
                        // 默认操作
                        break;
                }
                // 确保在事件结束后执行焦点操作
                BeginInvoke(new Action(() =>
                {
                    if (flag)
                    {
                        textBox1.Clear();
                        textBox1.Focus();
                        cmdRead.Text = "请扫描通道1二维码";
                    }
                    else
                    {
                        textBox2.Clear();
                        textBox2.Focus();
                        button1.Text = "请扫描通道2二维码";
                    }
                }));
            }
        }

        private void txtLog_TextChanged_1(object sender, EventArgs e)
        {

        }

        private void lstPorts_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void textBox3_TextChanged(object sender, EventArgs e)
        {

        }
    }
}





